package com.geoai.uimap.mvi.vm

import android.util.Log
import androidx.lifecycle.MutableLiveData
import com.geoai.basiclib.base.mvi.BaseEISViewModel
import com.geoai.mavlink.geoainet.flycontroller.info.FlyControllerStateInfo
import com.geoai.modservice.di.eventbus.OnMapClickEvent
import com.geoai.modservice.di.eventbus.OnMapTouchEvent
import com.geoai.uimap.model.GEOLatLng
import com.geoai.uimap.model.isLocationLegal
import com.geoai.uimap.mvi.eis.MapViewEffect
import com.geoai.uimap.mvi.eis.MapViewIntent
import com.geoai.uimap.mvi.eis.MapViewState
import com.geoai.uimap.utils.CoordinateUtils
import com.geoai.uimap.utils.SphericalUtil
import com.zkyt.lib_msdk_ext.component.FlyControllerManagerExt
import dagger.hilt.android.lifecycle.HiltViewModel
import io.reactivex.rxkotlin.addTo
import org.greenrobot.eventbus.EventBus
import javax.inject.Inject

/**
 * @Author      : Ronny
 * @Email       : Ronny_xie@hotmail.com
 * @Date        : on 2024-04-02 18:26.
 * @Description :
 */
@HiltViewModel
class GeoaiMapViewModel @Inject constructor(): BaseEISViewModel<MapViewEffect, MapViewIntent, MapViewState>() {

    val aircraftLocation: MutableLiveData<GEOLatLng> by lazy { MutableLiveData(GEOLatLng(0.0, 0.0)) }

    val isLockMapCameraByDroneLocation = MutableLiveData(false)

    val aircraftTrackPoints: MutableLiveData<MutableList<GEOLatLng>> by lazy { MutableLiveData(mutableListOf()) }

    var mapTouchPosition: Pair<Int, Int> = Pair(0, 0)

    init {
        registerFlightPositionStatus {fcStatus->

            val aircraftRotate = fcStatus.aircraftYaw

            val aircraftPos = GEOLatLng(fcStatus.aircraftLatitude, fcStatus.aircraftLongitude)

            val homePos = GEOLatLng(fcStatus.aircraftHomeLatitude, fcStatus.aircraftHomeLongitude)

            if (aircraftTrackPoints.value!!.isEmpty()) aircraftTrackPoints.value?.add(aircraftPos)

            val distanceInLastLocation = SphericalUtil.computeDistanceBetween(aircraftTrackPoints.value!!.last(), aircraftPos)

            aircraftLocation.postValue(aircraftPos)

            //小地图锁定
            if (uiStateFlow.value != MapViewState.MapBigView) sendEffect { MapViewEffect.CenterAtTargetLocation(aircraftPos) }
            //手动锁定
            if (isLockMapCameraByDroneLocation.value!!) sendEffect { MapViewEffect.CenterAtTargetLocation(aircraftPos) }

            if (aircraftPos.isLocationLegal()) {
                sendEffect { MapViewEffect.UpdateAircraftMarker(aircraftPos, aircraftRotate) }
            }
            if (homePos.isLocationLegal()) {
                sendEffect { MapViewEffect.UpdateAircraftReturnMarker(homePos) }
            }

            if (aircraftPos.isLocationLegal() && distanceInLastLocation > 3) {
                aircraftTrackPoints.value?.add(aircraftPos)
                sendEffect { MapViewEffect.UpdateAircraftTrackPolyline(aircraftTrackPoints.value!!) }
            }
        }
    }

    override fun initUiState(): MapViewState = MapViewState.MapBigView

    private fun toggleMapViewTouch() {
        if (uiStateFlow.value == MapViewState.MapBigView) return
        EventBus.getDefault().post(OnMapTouchEvent())
    }

    private fun toggleMapViewClick(location: GEOLatLng) {
        if (uiStateFlow.value != MapViewState.MapBigView) return
        EventBus.getDefault().post(OnMapClickEvent(location.latitude, location.longitude))
    }

    override fun handleIntent(intent: MapViewIntent) {
        when (intent) {
            MapViewIntent.OnMapTouchEvent -> toggleMapViewTouch()
            is MapViewIntent.OnMapClickEvent -> toggleMapViewClick(intent.location)
        }
    }

    private fun registerFlightPositionStatus(successBlock: (e: FlyControllerStateInfo) -> Unit) {
        FlyControllerManagerExt.getFlyControllerStateObservable()
            .filter { it.isPresent }
            .subscribe {
                successBlock.invoke(it.get())
            }.addTo(compositeDisposable)
    }
}